//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <bsp.h>
#include <init.h>
#include "pic.h"
#include <timer.h>

EXTERN_C DECL_CODEINIT void CDECL InitPIC()
{
    BspMaskAllIrqs(FALSE);
}

EXTERN_C irqs_t CDECL BspGetIrqs()
{
    return (irqs_t)Inl(_ICPND) | ((irqs_t)Inl(_ICPND2) << 32);
}

INLINE void EndOfInterrupt(irq_t irq)
{
    Outl(_ICSRC, 1 << irq);
    Outl(_ICPND, 1 << irq);
}

STATIC irqs_t s_irqMask = 0;

#if defined(_GNUC)


#define LLCONST(n)  n##ll
#elif defined(_EVC)

#define LLCONST(n)  n

#else

#error Unknown C++ compiler

#endif // defined(_GNUC)

EXTERN_C void CDECL BspMaskIrqs(irqs_t irqs, bool_t bEnable)
{
    if (bEnable)
        s_irqMask &= ~irqs;
    else
        s_irqMask |= irqs;

    if (irqs & LLCONST(0x00000000ffffffff)) {
        Outl(_ICMSK, (uint32_t)s_irqMask);
    }

    if (irqs & LLCONST(0xffffffff00000000)) {
        Outl(_ICMSK2, (uint32_t)(s_irqMask >> 32));
    }
}

EXTERN_C void CDECL BspMaskAllIrqs(bool_t bEnable)
{
    s_irqMask = bEnable? LLCONST(0x0000000000000000) : LLCONST(0xFFFFFFFFFFFFFFFF);

    Outl(_ICMSK, (uint32_t)s_irqMask);
    Outl(_ICMSK2, (uint32_t)(s_irqMask >> 32));
}

EXTERN_C void CDECL BspAcknowledgeIrq(irq_t irq)
{
    EndOfInterrupt(irq);
}
